home *** CD-ROM | disk | FTP | other *** search
/ Nautilus 1993 March / Nautilus-4-3 / Nautilus-4-3.bin / Multimedia / Feature / RlePict1.1 Folder / lib / rle_hdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-08  |  7.8 KB  |  289 lines

  1. /*
  2.  * This software is copyrighted as noted below.  It may be freely copied,
  3.  * modified, and redistributed, provided that the copyright notice is 
  4.  * preserved on all copies.
  5.  * 
  6.  * There is no warranty or other guarantee of fitness for this software,
  7.  * it is provided solely "as is".  Bug reports or fixes may be sent
  8.  * to the author, who may or may not act on them as he desires.
  9.  *
  10.  * You may not include this software in a program or other software product
  11.  * without supplying the source, or without informing the end-user that the 
  12.  * source is available for no extra charge.
  13.  *
  14.  * If you modify this software, you should include a notice giving the
  15.  * name of the person performing the modification, the date of modification,
  16.  * and the reason for such modification.
  17.  */
  18. /* 
  19.  * rle_hdr.c - Functions to manipulate rle_hdr structures.
  20.  * 
  21.  * Author:    Spencer W. Thomas
  22.  *         EECS Dept.
  23.  *         University of Michigan
  24.  * Date:    Mon May 20 1991
  25.  * Copyright (c) 1991, University of Michigan
  26.  */
  27. static char rcsid[] = "$Header: /l/spencer/src/urt/lib/RCS/rle_hdr.c,v 3.0.1.1 1992/04/30 14:08:07 spencer Exp $";
  28.  
  29. #include "rle.h"
  30.  
  31. /*****************************************************************
  32.  * TAG( rle_names )
  33.  *
  34.  * Load program and file names into header.
  35.  * Inputs:
  36.  *     the_hdr:    Header to modify.
  37.  *     pgmname:    The program name.
  38.  *     fname:        The file name.
  39.  *     img_num:    Number of the image within the file.
  40.  * Outputs:
  41.  *     the_hdr:    Modified header.
  42.  * Algorithm:
  43.  *     If values previously filled in (by testing is_init field),
  44.  *     free them.  Make copies of file name and program name,
  45.  *     modifying file name for standard i/o.  Set is_init field.
  46.  */
  47. void
  48. rle_names( the_hdr, pgmname, fname, img_num )
  49. rle_hdr *the_hdr;
  50. CONST_DECL char *pgmname;
  51. CONST_DECL char *fname;
  52. int img_num;
  53. {
  54. #if 0
  55.     /* Can't do this because people do hdr1 = hdr2, which copies
  56.        the pointers. */
  57.  
  58.     /* If filled in, free previous values. */
  59.     if ( the_hdr->is_init == RLE_INIT_MAGIC &&
  60.      the_hdr->cmd != NULL && the_hdr->file_name != NULL )
  61.     {
  62.     if ( pgmname != the_hdr->cmd )
  63.         free( the_hdr->cmd );
  64.     if ( fname != the_hdr->file_name )
  65.         free( the_hdr->file_name );
  66.     }
  67. #endif
  68.  
  69.     /* Mark as filled in. */
  70.     the_hdr->is_init = RLE_INIT_MAGIC;
  71.  
  72.     /* Default file name for stdin/stdout. */
  73.     if ( fname == NULL || strcmp( fname, "-" ) == 0 || *fname == '\0' )
  74.     fname = "Standard I/O";
  75.     if ( pgmname == NULL )
  76.     pgmname = "URT";
  77.  
  78.     /* Fill in with copies of the strings. */
  79.     if ( the_hdr->cmd != pgmname )
  80.     {
  81.     char *tmp = (char *)malloc( strlen( pgmname ) + 1 );
  82.     RLE_CHECK_ALLOC( pgmname, tmp, 0 );
  83.     strcpy( tmp, pgmname );
  84.     the_hdr->cmd = tmp;
  85.     }
  86.  
  87.     if ( the_hdr->file_name != fname )
  88.     {
  89.     char *tmp = (char *)malloc( strlen( fname ) + 1 );
  90.     RLE_CHECK_ALLOC( pgmname, tmp, 0 );
  91.     strcpy( tmp, fname );
  92.     the_hdr->file_name = tmp;
  93.     }
  94.  
  95.     the_hdr->img_num = img_num;
  96. }
  97.  
  98.  
  99. /* Used by rle_hdr_cp and rle_hdr_init to avoid recursion loops. */
  100. static int no_recurse = 0;
  101.  
  102. /*****************************************************************
  103.  * TAG( rle_hdr_cp )
  104.  * 
  105.  * Make a "safe" copy of a rle_hdr structure.
  106.  * Inputs:
  107.  *     from_hdr:    Header to be copied.
  108.  * Outputs:
  109.  *     to_hdr:        Copy of from_hdr, with all memory referred to
  110.  *             by pointers copied.  Also returned as function
  111.  *             value.  If NULL, a static header is used.
  112.  * Assumptions:
  113.  *     It is safe to call rle_hdr_init on to_hdr.
  114.  * Algorithm:
  115.  *     Initialize to_hdr, copy from_hdr to it, then copy the memory
  116.  *     referred to by all non-null pointers.
  117.  */
  118. rle_hdr *
  119. rle_hdr_cp( from_hdr, to_hdr )
  120. rle_hdr *from_hdr, *to_hdr;
  121. {
  122.     static rle_hdr dflt_hdr;
  123.     CONST_DECL char *cmd, *file;
  124.     int num;
  125.  
  126.     /* Save command, file name, and image number if already initialized. */
  127.     if ( to_hdr &&  to_hdr->is_init == RLE_INIT_MAGIC )
  128.     {
  129.     cmd = to_hdr->cmd;
  130.     file = to_hdr->file_name;
  131.     num = to_hdr->img_num;
  132.     }
  133.     else
  134.     {
  135.     cmd = file = NULL;
  136.     num = 0;
  137.     }
  138.  
  139.     if ( !no_recurse )
  140.     {
  141.     no_recurse++;
  142.     rle_hdr_init( to_hdr );
  143.     no_recurse--;
  144.     }
  145.  
  146.     if ( to_hdr == NULL )
  147.     to_hdr = &dflt_hdr;
  148.  
  149.     *to_hdr = *from_hdr;
  150.  
  151.     if ( to_hdr->bg_color )
  152.     {
  153.     int size = to_hdr->ncolors * sizeof(int);
  154.     to_hdr->bg_color = (int *)malloc( size );
  155.     RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" );
  156.     bcopy( from_hdr->bg_color, to_hdr->bg_color, size );
  157.     }
  158.  
  159.     if ( to_hdr->cmap )
  160.     {
  161.     int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map);
  162.     to_hdr->cmap = (rle_map *)malloc( size );
  163.     RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" );
  164.     bcopy( from_hdr->cmap, to_hdr->cmap, size );
  165.     }
  166.  
  167.     /* Only copy array of pointers, as the original comment memory
  168.      * never gets overwritten.
  169.      */
  170.     if ( to_hdr->comments )
  171.     {
  172.     int size = 0;
  173.     CONST_DECL char **cp;
  174.     for ( cp=to_hdr->comments; *cp; cp++ )
  175.         size++;        /* Count the comments. */
  176.     /* Check if there are really any comments. */
  177.     if ( size )
  178.     {
  179.         size++;        /* Copy the NULL pointer, too. */
  180.         size *= sizeof(char *);
  181.         to_hdr->comments = (CONST_DECL char **)malloc( size );
  182.         RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" );
  183.         bcopy( from_hdr->comments, to_hdr->comments, size );
  184.     }
  185.     else
  186.         to_hdr->comments = NULL;    /* Blow off empty comment list. */
  187.     }
  188.  
  189.     /* Restore the names to their original values. */
  190.     to_hdr->cmd = cmd;
  191.     to_hdr->file_name = file;
  192.  
  193.     /* Lines above mean nothing much happens if cmd and file are != NULL. */
  194.     rle_names( to_hdr, to_hdr->cmd, to_hdr->file_name, num );
  195.  
  196.     return to_hdr;
  197. }
  198.  
  199. /*****************************************************************
  200.  * TAG( rle_hdr_clear )
  201.  * 
  202.  * Clear out the allocated memory pieces of a header.
  203.  *
  204.  * This routine is intended to be used internally by the library, to
  205.  * clear a header before putting new data into it.  It clears all the
  206.  * fields that would be set by reading in a new image header.
  207.  * Therefore, it does not clear the program and file names.
  208.  * 
  209.  * Inputs:
  210.  *     the_hdr:    To be cleared.
  211.  * Outputs:
  212.  *     the_hdr:    After clearing.
  213.  * Assumptions:
  214.  *     If is_init field is RLE_INIT_MAGIC, the header has been
  215.  *     properly initialized.  This will fail every 2^(-32) times, on
  216.  *     average.
  217.  * Algorithm:
  218.  *     Free memory and set to zero all pointers, except program and
  219.  *     file name.
  220.  */
  221. void
  222. rle_hdr_clear( the_hdr )
  223. rle_hdr *the_hdr;
  224. {
  225.     /* Try to free memory.  Assume if is_init is properly set that this
  226.      * header has been previously initialized, therefore it is safe to
  227.      * free memory.
  228.      */
  229.     if ( the_hdr && the_hdr->is_init == RLE_INIT_MAGIC )
  230.     {
  231.     if ( the_hdr->bg_color )
  232.         free( the_hdr->bg_color );
  233.     the_hdr->bg_color = 0;
  234.     if ( the_hdr->cmap )
  235.         free( the_hdr->cmap );
  236.     the_hdr->cmap = 0;
  237.     /* Unfortunately, we don't know how to free the comment memory. */
  238.     if ( the_hdr->comments )
  239.         free( the_hdr->comments );
  240.     the_hdr->comments = 0;
  241.     }
  242. }
  243.  
  244.  
  245.  
  246. /*****************************************************************
  247.  * TAG( rle_hdr_init )
  248.  * 
  249.  * Initialize a rle_hdr structure.
  250.  * Inputs:
  251.  *     the_hdr:    Header to be initialized.
  252.  * Outputs:
  253.  *     the_hdr:    Initialized header.
  254.  * Assumptions:
  255.  *     If the_hdr->is_init is RLE_INIT_MAGIC, the header has been
  256.  *     previously initialized.
  257.  *     If the_hdr is a copy of another rle_hdr structure, the copy
  258.  *     was made with rle_hdr_cp.
  259.  * Algorithm:
  260.  *    If the_hdr is rle_dflt_hdr, do nothing!
  261.  *    If the_hdr is NULL, return a copy of rle_dflt_hdr.
  262.  *     If the_hdr->is_init is RLE_INIT_MAGIC, free all memory
  263.  *     pointed to by non-null pointers.
  264.  *     Copy rle_dflt_hdr into the_hdr.
  265.  */
  266. rle_hdr *
  267. rle_hdr_init( the_hdr )
  268. rle_hdr *the_hdr;
  269. {
  270.     rle_hdr *ret_hdr;
  271.  
  272.     if ( the_hdr == &rle_dflt_hdr )
  273.     return the_hdr;
  274.  
  275.     rle_hdr_clear( the_hdr );
  276.  
  277.     /* Only call rle_hdr_cp if not called from there. */
  278.     if ( !no_recurse )
  279.     {
  280.     no_recurse++;
  281.     ret_hdr = rle_hdr_cp( &rle_dflt_hdr, the_hdr );
  282.     no_recurse--;
  283.     }
  284.     else
  285.     ret_hdr = the_hdr;
  286.  
  287.     return ret_hdr;
  288. }
  289.